﻿using Axiom.Core;
using Axiom.Math;
using Utility.Input;
using System.Windows.Forms;

namespace Utility.Navigation 
{
    class FpsNavigationManager : NavigationManager {

        public FpsNavigationManager(QuadtreeSceneManager q, Camera c, InputReader i, Control u)
            : base(q, c, i, u)
        {
            camera.Position = Vector3.UnitZ * Planet.OuterOrbitRadius;
            camera.LookAt(Vector3.Zero);
            camera.Near = 100f;
            camera.Far = camera.Position.Length * 2.5f;
            //initialization : find the first azimuth and elevation angles of the current position
		}

        public override void Navigate(FrameEventArgs e)
        {
            // TODO : input.Capture Render.onFrameStart ta olmali ama orada calismiyor. Neden anla, duzelt?
            input.Capture();

            //fps mouse camera
            camera.Yaw(-input.RelativeMouseX * .33f);
            camera.Pitch(-input.RelativeMouseY * .33f);

            float camSpeed = 90000 * (camera.Position.Length) / (Planet.OuterOrbitRadius * VectorProjection.PARAMETER_UNIT_FACTOR);

            if (input.IsKeyPressed(KeyCodes.W))
            {
                camera.Move(camera.Direction * camSpeed);
            }

            if (input.IsKeyPressed(KeyCodes.S))
            {
                camera.Move(-camera.Direction * camSpeed);
            }
            if (input.IsKeyPressed(KeyCodes.Q) || input.IsKeyPressed(KeyCodes.Left))
            {
                camera.Yaw(5);
            }

            if (input.IsKeyPressed(KeyCodes.E) || input.IsKeyPressed(KeyCodes.Right))
            {
                camera.Yaw(-5);
            }
            if (input.IsKeyPressed(KeyCodes.Up))
            {
                camera.Pitch(5);
            }
            if (input.IsKeyPressed(KeyCodes.Down))
            {
                camera.Pitch(-5);
            }

            //strafe
            if (input.IsKeyPressed(KeyCodes.A))
            {
                Vector3 camDirHorizontal = camera.Direction;
                camDirHorizontal.y = 0;
                camDirHorizontal = -camDirHorizontal.Cross(Vector3.UnitY);
                camDirHorizontal.Normalize();
                camera.Move(camDirHorizontal * camSpeed);
            }

            //strafe
            if (input.IsKeyPressed(KeyCodes.D))
            {
                Vector3 camDirHorizontal = camera.Direction;
                camDirHorizontal.y = 0;
                camDirHorizontal = camDirHorizontal.Cross(Vector3.UnitY);
                camDirHorizontal.Normalize();
                camera.Move(camDirHorizontal * camSpeed);
            }

            if (camera.Position.Length > (Planet.OuterOrbitRadius * VectorProjection.PARAMETER_UNIT_FACTOR))
            {
                camera.Position = (camera.Position / camera.Position.Length) * (Planet.OuterOrbitRadius * VectorProjection.PARAMETER_UNIT_FACTOR);
            }

            if (camera.Position.Length < (Planet.InnerOrbitRadius * VectorProjection.PARAMETER_UNIT_FACTOR))
            {
                camera.Position = (camera.Position / camera.Position.Length) * (Planet.InnerOrbitRadius * VectorProjection.PARAMETER_UNIT_FACTOR);
            }
		}
	}//end GlobeNavigation
}//end namespace Navigation